﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using wordroid.Model;
using wordroid.ViewModel;

namespace wordroid.utils
{
    public class XMLParser {

        /* original xml
         <?xml version=\"1.0\" encoding=\"UTF-8\"?>
            <words>
                <word>

                    <original_word>Первый</original_word>

                    <trans>trans_1</trans>
                    <trans>trans_2</trans>
                    <trans>trans_3</trans>

                    <invalid_trans>inv_trans_1</invalid_trans>
                    <invalid_trans>inv_trans_2</invalid_trans>
                    <invalid_trans>inv_trans_3</invalid_trans>
                </word>
            </words>
         */

        private static List<XmlWord> parseWords(String xml) {
            XDocument doc = XDocument.Parse(xml);

            List<XmlWord> xmlwords = (from word in doc.Descendants(Constants.XML_WORD)
                                      select new XmlWord {
                                          Word = word.Element(Constants.XML_ORIGINAL_WORD).Value,
                                          Trans = word.Descendants(Constants.XML_TRANS).ToList(),
                                          InvTrans = word.Descendants(Constants.XML_INV_TRANS).ToList()
                                                           }).ToList();
            return xmlwords;
        }

        public static void LoadAndsave(String xml, EventHandler handler) {

            List<XmlWord> xmlwords = parseWords(xml);
            if(xmlwords != null && !xmlwords.Any()) {
                return; //success if emty
            }

            try {
                foreach (XmlWord xmlWord in xmlwords) {
                    DBHelper helper = DBHelper.getInstance();
                    int? id = helper.isWordExists(xmlWord.Word);

                    if (id != null) {
                        helper.EditWord(id, xmlWord.Word, xmlWord.STrans, xmlWord.SInvTrans);
                    }
                    else {
                        helper.SaveWordAsNew(xmlWord.Word, xmlWord.STrans, xmlWord.SInvTrans);
                    }
                }

                handler.Invoke(null, new DownloadManagerEventArgs() {Success = true});
            }catch(Exception e) {
                handler.Invoke(null, new DownloadManagerEventArgs() { Success = false, failCause = e.Message});
            }
        }
    }

    internal class XmlWord {

        public string Word { get; set; }
        public List<XElement> Trans { get; set; }
        public List<XElement> InvTrans { get; set; }

        public List<String> STrans {
            get {
                if(trans == null || !trans.Any()) {
                    trans = toStringlist(Trans);
                }
                return trans;
            }
        }

        public List<String> SInvTrans {
            get {
                if (invTrans == null || !invTrans.Any()) {
                    invTrans = toStringlist(InvTrans);
                }
                return invTrans;
            }
        }

        private List<String> toStringlist(List<XElement> elementsList) {
            List<String> transList = new List<String>();
                if (elementsList != null && elementsList.Any()) {
                    foreach (XElement element in elementsList) {
                        if (!transList.Contains(element.Value)) {
                            transList.Add(element.Value);
                        }
                    }
                }
            return transList;
        }

        public bool IsCorrect {
            get {
                if(Word == null || String.IsNullOrWhiteSpace(Word)) {
                    return false;
                }

                return STrans != null && STrans.Any() && SInvTrans != null && SInvTrans.Any();
            }
        }

        private static List<String> trans;
        private static List<String> invTrans;
    }
}
